<template>
    <!-- 三级列表 -->
    <Category :disabled="isShowList"/>

    <el-card shadow="always" :body-style="{ padding: '20px' }" :style="{marginTop: '40px'}">

        <!-- 商品属性表格 -->
        <template #header v-if="!isShowList">
            <el-button type="primary" :disabled="!category3Id"  @click="addAttr" :icon="CirclePlusFilled">添加</el-button>   
        </template> 
        <el-table :data="tableData"  border stripe v-if="!isShowList">
            <el-table-column type="index" width="80" align="center" label="序号"/>
            <el-table-column label="属性名称" width="150" prop="attrName"></el-table-column>
            <el-table-column label="属性名称列表" >
                <template #="{row}">
                    <el-tag 
                        :style="{marginRight: '16px'}"
                        type="success" 
                        size="default" 
                        v-for="item in row.attrValueList" 
                        :key="item.id"
                    >{{item.valueName}}</el-tag>
                </template>
            </el-table-column>
            <el-table-column label="操作" width="150">
                <template #="{row}">
                    <el-button type="warning" size="default" :icon="Edit" @click="upDateAtrr(row)"></el-button>
                    <!-- 气泡确认框 -->
                    <el-popconfirm title="确定要删除吗?" @confirm="deleteAttr(row.id)">
                        <template #reference>
                            <el-button type="danger" size="default" :icon="DeleteFilled" ></el-button>
                        </template>
                    </el-popconfirm>
                </template>
            </el-table-column>
        </el-table>

        <!-- 添加或修改商品属性页面 -->
        <div v-else>
            <!-- 输入框 -->
            <el-form :inline="true">
                <el-form-item label="属性名">
                    <el-input v-model="newAttr.attrName"></el-input>
                </el-form-item>
            </el-form>
            <!-- 添加属性值按钮 -->
            <div>
                <el-button :disabled="!newAttr.attrName" type="primary"  @click="addAttrValue" >添加属性值</el-button>
                <el-button @click="isShowList = false">取消</el-button>
            </div>
            <!-- 属性值表格 -->
            <el-table :data="newAttr.attrValueList"  border stripe :style="{marginTop: '30px' , marginBottom: '30px'}">
                <el-table-column type="index" width="100" label="序号" align="center"/>
                <el-table-column label="属性值名称">
                    <template #="{row , $index}">
                        <span 
                            v-if="!row.isEdit" 
                            @click="toEdit(row)"
                            :style="{display: 'inline-block' , width: '70%'}"
                        >{{row.valueName}}</span>
                        <el-input
                            v-else 
                            v-model="row.valueName" 
                            placeholder="请输入属性名" 
                            ref="inputEle"
                            @focus="getOldAttrValue(row)"
                            @blur="toLook(row , $index)"
                        ></el-input>
                    </template>
                </el-table-column>
                <el-table-column label="操作">
                    <template #="{$index}">
                        <!-- 气泡确认框 -->
                        <el-popconfirm title="确定要删除吗?" @confirm="deleteAttrValue($index)">
                            <template #reference>
                                <el-button type="danger" icon="ele-Delete"></el-button>
                            </template>
                        </el-popconfirm>
                    </template>
                </el-table-column>
            </el-table>
            <!-- 保存和取消按钮 -->
            <div>
                <el-button :disabled="newAttr.attrValueList.length<=0  || !newAttr.attrName" type="primary"  @click="addOrUpdateAttr">保存</el-button>
                <el-button @click="isShowList = false">取消</el-button>
            </div>
        </div>

    </el-card>

</template>

<script lang="ts">
import { defineComponent } from "vue";
import { storeToRefs } from "pinia";
import { ElMessage } from "element-plus";

export default defineComponent({
    name: "Attr",
});
</script>

<script setup lang="ts">
import {CirclePlusFilled , Edit , DeleteFilled} from "@element-plus/icons-vue"
import {watch , ref, nextTick} from "vue"
import type {reqAttrListType , reqAttrItemType , reqAttrValueType} from "@/api/attr"
import {requestGetAttrList , requestUpdateOrAddAttr , requestDeleteAttr} from "@/api/attr"
import useAttrStore from "@/stores/attr";
import  cloneDeep  from "lodash/cloneDeep";
const attrStore = useAttrStore()
const {category1Id , category2Id , category3Id}  = storeToRefs(attrStore)


//1.商品属性列表逻辑·
//定义数据保存做商品属性列表
const tableData = ref<reqAttrListType>([])
//封装请求商品属性列表的函数
const getAttrList = async() => {
    try {
        //发送请求
        const result = await  requestGetAttrList(
            category1Id.value as number , 
            category2Id.value as number ,
            category3Id.value as number ,
        )
        //把请求回来的属性列表的数据给到组件中
        tableData.value = result
    }catch(e) {
        ElMessage.error("请求商品属性列表失败!!!")
    }
}
//监听category3Id的改变发送商品属性列表请求
watch(category3Id , async(newVal)=>{
    //点击一级二级列表会把category3Id改为null，把商品属性列表清空，不往下执行
    if(!newVal){
        tableData.value = []
        return
    }
    //正常的3Id就开始请求商品属性列表
    getAttrList()
} , {immediate: true})



//2.添加或修改商品属性逻辑:
//定义数据控制添加或修改商品属性页面显示隐藏
const isShowList = ref(false)
//定义添加或修改商品属性要发送的数据
const newAttr = ref<reqAttrItemType>({
    attrName: "",
    categoryId: category3Id.value as number,
    categoryLevel: 3,
    attrValueList: []
})

//2.1点击新增属性的回调
const addAttr = () => {
    //点击新增先显示添加或修改页面
    isShowList.value = true
    //在清空数据
    newAttr.value = {
        attrName: "",
        categoryId: category3Id.value as number,
        categoryLevel: 3,
        attrValueList: []
    }
}
//2.2点击修改属性的回调
const upDateAtrr = (row: reqAttrItemType) => {
    //2.2.1点击修改先显示添加或修改页面
    isShowList.value = true
    //2.2.2数据回填之前给属性值列表数组的每一项添加一个isEdit 控制编辑和查看状态
    const newRow = cloneDeep(row)
    newRow.attrValueList.forEach((item) => {
        item.isEdit = false
    })
    //2.2.3数据回填
    newAttr.value = newRow
}

//2.3点击添加属性值的回调
const addAttrValue = () => {
    //2.3.1点击添加属性值创建一条新的属性值数据
    const newAttrValue = {
        valueName: "", //属性名
        attrId: 0,     //属性id
        isEdit: true //代表新添加的数据默认是编辑状态
    }
    //2.3.2把数据添加到newAttr中的属性值列表的数组中
    newAttr.value.attrValueList.push(newAttrValue)
    //2.3.3每添加一个数据就自动获取焦点 为了拿到旧值
    nextTick(()=>{
        inputEle.value.focus()
    })
}

//获取表单元素
const inputEle = ref()
//定义旧值
let oldAttrValueName = ""

//获取焦点的回调 拿到旧值
const getOldAttrValue = (row: reqAttrValueType) => {
    oldAttrValueName = row.valueName 
    console.log(oldAttrValueName);
    
}

//2.4点击span切换到编辑模式的回调
const toEdit = (row: reqAttrValueType) => {
    //切换当前span为input
    row.isEdit = true
    //切换为input状态立刻获取焦点 为了拿到旧值
    nextTick(()=>{
        inputEle.value.focus()
    })
}

//2.5input失去焦点改变为span的回调
const toLook = (row: reqAttrValueType , $index: number) => {
    //2.5.1先切换为span
    row.isEdit = false

    //2.5.2判断输入为空
    if(!row.valueName){
        if(!oldAttrValueName){
            //如过没有旧值,代表用户添加了一条空数据,我们把他删除
            newAttr.value.attrValueList.splice($index , 1)
        }else{
            //如果有旧值,代表用户删除了数据,我们把它还原
            row.valueName = oldAttrValueName
        }
    }

    //2.5.3判断输入重复 输入后和其他所有值进行比较
    const isRepeat = newAttr.value.attrValueList.some((item) => {
        if(item === row) return
        return item.valueName === row.valueName
    })
    //如果输入的内容重复了还有两种情况
    if(isRepeat){
            //旧值为空,说明添加了一个值和数组中的值重复,我们把这个添加的值删除
        if(!oldAttrValueName){
            newAttr.value.attrValueList.splice($index , 1)
        }else{
            //旧值不为空,说明修改数组中的值之后和数组中的值重复,我们把这个值还原
            row.valueName = oldAttrValueName
        }
    }

    //失去焦点后统一清空旧值
    oldAttrValueName = ""
    
}

//2.6点击删除属性值的回调
const deleteAttrValue = ($index: number) => {
    //删除数组中的当前这一条数据
    newAttr.value.attrValueList.splice($index , 1)
}

//2.7点击保存的回调
const addOrUpdateAttr = async () => {
    //发送添加或修改请求
    try {
        //发送请求
        await requestUpdateOrAddAttr(newAttr.value)
        //成功提示
        ElMessage.success(newAttr.value.id? '修改成功~' : '添加成功~')
        //显示商品属性列表
        isShowList.value = false
        //重新请求商品属性列表
        getAttrList()
    } catch (error) {
        //失败提示
        ElMessage.error(newAttr.value.id? '修改失败~' : '添加失败~')
    }
}

//3.点击删除属性的回调
const deleteAttr = async (id: number) => {
    try {
        //删除请求
        await requestDeleteAttr(id)
        //提示
        ElMessage.success("删除成功!")
        //重新请商品属性列表
        getAttrList()
    } catch (error) {
        //失败提示
        ElMessage.error("删除失败!")     
    }
}




</script>